home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / CRS / crs49.d81 / hack2-2.sfx / hack.2
Text File  |  1990-02-12  |  47KB  |  1,000 lines

  1.          ┼ND;
  2.  
  3.       ╫RITELN;
  4.       ╫RITELN ('╩OB ├OMPLETED :-)');
  5.  
  6.    END;
  7.  
  8.    ╞OR ├OUNTER := 1 TO 3 DO
  9.       ╫RITELN;
  10.    █ ═AKE A BIT OF SPACE WHEN FINISHED :-) ▌
  11. END.
  12.  
  13. ================================================================================
  14. ┬┴╬╦╔╬╟ ╧╬ ╟┼╧╙
  15.  
  16. BY ╥OBERT ┴. ╦NOP ╩R.
  17.  
  18. ╔. ╔NTRODUCTION
  19.  
  20. ╟┼╧╙ WAS ORIGINALLY WRITTEN FOR THE ├OMMODORE 64.  ╫HEN ┬ERKELEY ╙OFTWORKS
  21. CAME OUT WITH ╟┼╧╙128 (AND, FOR A TIME, IT WASN'T CLEAR THAT THEY WOULD; THEN,
  22. IT LOOKED LIKE THEY WOULD RELEASE A ╟┼╧╙128 THAT WOULDN'T SUPPORT THE 80
  23. COLUMN SCREEN; FINALLY, THE RELEASE OF ╟┼╧╙128 DID TURN OUT TO BE A FULL 128
  24. PROGRAM), IT WAS LARGELY COMPATIBLE WITH ╟┼╧╙64.  ┴PPLICATIONS COULD SHARE
  25. DOCUMENTS (A GEO╨AINT FILE IS A GEO╨AINT FILE), AND EVEN MANY ╟┼╧╙64
  26. APPLIATIONS RUN ON THE 128 IN 40 COLUMNS.  ╘HIS HERITAGE IS ALSO EVIDENT TO
  27. THE ╟┼╧╙ PROGRAMMER.
  28.  
  29. ┴S WE ALL KNOW, THE ├-128 HAS TWO 64╦ ╥┴═ BANKS; THE ├-64 ONLY HAS ONE 64╦ ╥┴═
  30. "BANK."  ╘HUS, OF COURSE, ALL OF ╟┼╧╙64 GOES INTO THAT ONE 64╦ ╥┴═ SPACE.
  31. ╘HIS INCLUDES THE ╦ERNAL AS WELL AS THE SPACE AVAILABLE TO APPLICATIONS.  ╧NCE
  32. THE ╦ERNAL, GRAPHICS SCREENS, AND SO FORTH, HAVE CLAIMED THEIR ╥┴═, THE ╟┼╧╙
  33. PROGRAMMER IS LEFT WITH 23.75╦ OF MEMORY FROM $0400 TO $5FFF.
  34.  
  35. ╘O A CURSORY "GLANCE," THE ╟┼╧╙128 PROGRAMMING ENVIRONMENT LOOKS VERY MUCH
  36. LIKE THE ╟┼╧╙64 PROGRAMMING ENVIROMENT.  ┘OU STILL HAVE $0400 TO $5FFF
  37. AVAILABLE FOR APPLICATIONS; GRAPHICS SCREENS AND VARIABLES ARE IN THE SAME
  38. PLACE; THE ╦ERNAL JUMP TABLE IS THE SAME (WITH SOME 128 SPECIFIC ADDITIONS).
  39. ╫HAT HAPPENED TO THE OTHER 64╦ THAT THE 128 HAS AVAILABLE?
  40.  
  41. ┴S IT TURNS OUT, THE CORE OF ╟┼╧╙128- INCLUDING THE APPLICATION PROGRAM SPACE,
  42. THE 40 COLUMN FOREGROUND AND BACKGROUND SCREEN, AND THE ╦ERNAL JUMP TABLE- ARE
  43. ALL IN THE 128'S ╥┴═ BLOCK 1, WHAT ╟┼╧╙ CALLS ╞RONT╥┴═.  ╘O US 128 PROGRAMMERS
  44. USED TO ╥┴═ BLOCK 0 BEING THE "MAIN" ╥┴═ BLOCK, THIS MAY SOUND ODD.  ╚OWEVER,
  45. IT ACTUALLY MAKES SENSE.  ╞IRST OF ALL, SINCE ╟┼╧╙ IS AN OPERATING SYSTEM IN
  46. AND OF ITSELF, AND APPLICATIONS ALMOST NEVER NEED TO CALL THE ├128'S ╦ERNAL
  47. ROUTINES, THE APPLICATION NO LONGER NEEDS ACCESS TO ┬ANK 15.  ╙ECOND, IT
  48. ALLOWS ╟┼╧╙128 TO KEEP MUCH OF ITS MEMORY MAP THE SAME AS ╟┼╧╙64; IT CAN USE
  49. THE MEMORY RANGE FROM $200-$3FF IN ╥┴═ 1 WITHOUT WORRYING ABOUT DISTURBING KEY
  50. SYSTEM ROUTINS LIKE ╙╘┴╞┴╥ WHICH ARE IN THE SAME MEMORY RANGE IN ╥┴═ 0.
  51.  
  52.  
  53. ╔╔. ┘EAH, ┘EAH, ┬UT ╫HAT ╚APPENED TO ╥┴═ 0 ┴NYWAY?
  54.  
  55. ╔T'S STILL THERE.  ╙OME OF ╥┴═ 0 IS USED BY ╟┼╧╙128 TO IMPROVE THE SYSTEM
  56. PERFORMANCE AND TO TAKE ADVANTAGE OF THE 128'S UNIQUE FEATURES.  (╞OR
  57. INSTANCE, THE CODE FOR THE "SOFTWARE SPRITES" SEE ON THE 128'S 80 COLUMN
  58. SCREEN IS FOUND BENEATH $2000 IN ╥┴═ 0.)  ╞ORTUNATELY, SOME SPACE DOES REMAIN
  59. AVAILABLE FOR AN APPLICATION TO USE.  ╔N ╥┴═ 0, THE 32╦ MEMORY SPACE BETWEEN
  60. $2000 AND $9FFF IS NOT NORMALLY USED BY ╟┼╧╙, AND IS ┴╠═╧╙╘ AVAILABLE FOR
  61. APPLICATION USE [1].
  62.  
  63. ╫HY DO ╔ SAY "ALMOST"?  ╘HE PROBLEM IS DESK ACCESSORIES.  ╫HEN ╟┼╧╙ 64 LOADS A
  64. DESK ACCESSORY (─┴), IT MUST LOAD IT INTO THE SAME APPLICATION SPACE AS THE
  65. APPLICATION LOADING THE ─┴.  ╘HE MEMORY THAT THE ─┴ WILL USED IS FIRST SAVED
  66. TO DISK IN A SWAP FILE.  ╒NDER ╟┼╧╙128, THE ROUTINE ╠D─ESK┴CC, INSTEAD OF
  67. SAVING A SWAP FILE TO DISK, COPIES THE MEMORY TO BE OVERWRITTEN BY THE ─┴ TO
  68. ╥┴═0 BETWEEN $2000 AND $9FFF.  ╙O, IF YOUR APPLICATION USES ─┴'S (AND IT IS
  69. HIGHLY RECOMMENDED THAT MAJOR APPLICATIONS SUPPORT ─┴'S), YOU HAVE TO BE
  70. CAREFUL USING THE SPACE BETWEEN $2000 AND $9FFF.  ┘OU CAN USE IT AS TEMPORARY
  71. SWAP SPACE WITHIN ROUTINES- BUT YOU CANNOT ASSUME THAT IT WILL REMAIN INTACT
  72. WHENEVER YOUR ROUTINE RETURNS TO THE ╟┼╧╙ ═AIN╠OOP WITH YOUR APPLICATION IN A
  73. STATE THAT WILL ALLOW THE LOADING OF ─┴'S.
  74.  
  75. ╬OWADAYS, ╥┴═ 0 IS NOT THE BE-ALL AND END-ALL.  ╟┼╧╙128 WAS WRITTEN FOR THE
  76. ├=128, NOT THE ├=256.  ├ONSEQUENTLY, IF YOU HAVE EXPANDED YOUR 128 TO 256╦ OR
  77. 512╦ AS DESCRIBED IN THE ARTICLES BY ╥ICHARD ├URCIO IN ╘WIN ├ITIES 128 ╔SSUES
  78. #30 AND #31 [2,3], YOU HAVE FREE USE OF ╥┴═ 2-3 (256╦) OR ╥┴═ 2-7 (512╦).
  79. (╬OTE THAT YOU SHOULD NOT TOUCH ╥┴═ 4-7 ON A 512╦ 128 IF YOU WANT TO BE
  80. COMPATIBLE WITH TASK SWITCHING AS DESCRIBED IN ╘├128 #31.  ┴LSO, ALTHOUGH ╟┼╧╙
  81. RIGHT NOW DOES NOT RUN IN THE 2ND 256╦, APPLICATIONS SHOULD NOT ASSUME THEY
  82. ARE IN THE 1ST 256╦, AND THUS SHOULD BE CAREFUL WITH THE 512╦ MODE BITS (4-5)
  83. IN THE ══╒ ╥AM ├ONFIGURATION ╥EGISTER (╥├╥), $D506.)  ╫HILE THE NUMBER OF
  84. PEOPLE WITH 256╦ AND 512╦ 128'S IS NOW SMALL, YOU CAN BE SURE THAT IT WILL
  85. INCREASE WHEN THE PROMISED ┌╔╨ ACCELERATOR BOARD FOR THE 128 COMES OUT; THE
  86. CURRENT SPECS FOR THE ┌╔╨ BOARD INCLUDE PROVISIONS FOR MEMORY EXPANSION ON THE
  87. BOARD.
  88.  
  89. ╥┴═ 2-3 PROVIDE ALMOST ANOTHER COMPLETE 128╦ AVAILABLE FOR YOUR APPLICATION TO
  90. USE.  ╙O HOW DO YOU GO ABOUT ACCESSING THIS?
  91.  
  92.  
  93. ╔╔╔. ╙TORING ─ATA ╔N ╧THER ╥┴═ ┬LOCKS
  94.  
  95. ╘HE MOST OBVIOUS USE FOR ╥┴═ BLOCKS OTHER THAN ╞RONT╥┴═ (WHICH IS THE ONLY
  96. BLOCK WHERE ╟┼╧╙ ╦ERNAL ROUTINES ARE AVAILABLE) IS AS DATA STORAGE.  ╞OR
  97. INSTANCE, ONE COULD VISUALIZE A GEO╨AINT PREVIEWING UTILITY WHICH LOADS AND
  98. DECOMPACTS AN ENTIRE GEO╨AINT DOCUMENT AT ONCE TO ╥┴═ 2.  (╘HE FULL
  99. DECOMPACTED GEO╨AINT DOCUMENT WOULD REQIRE 56.25╦.)  ╧NE COULD THEN QUICKLY
  100. SCROLL THROUGH THE DOCUMENT BY JUST COPYING THE RELEVANT PORTIONS OF THE
  101. BITMAP FROM ╥┴═ 2 TO THE FOREGROUND SCREEN.  ╧R, IF ONE WERE REALLY BOLD, ONE
  102. COULD JUST REDIRECT THE ╓╔├ SCREEN MEMORY TO THE RELEVANT RANGE IN ╥┴═2 USING
  103. THE PROPER ══╒ AND ╓╔├ REGISTERS.  (╘HIS WOULD ACTULLY REQUIRE USE OF BOTH ╥┴═
  104. 2 AND 3, SINCE ╓╔├ SCREEN LOCATIONS ARE QUANTIZED TO 8╦; YOU LOSE THE USE OF
  105. THE HIGHEST 8╦, SINCE YOU DON'T WANT TO OVERWRITE THE ══╒ REGISTERS AT
  106. $FF00-$FF05; ADDITIONAL PRACTICAL CONSIDERATIONS MAKE USE OF THE LOWEST 8╦
  107. DIFFICULT.)
  108.  
  109. ╟┼╧╙128 PROVIDES A FEW ROUTINES FOR EASILY MOVING DATA BETWEEN ╞RONT╥┴═ AND
  110. WHAT IT CALLS ┬ACK╥┴═ (BUT WE KNOW IT JUST MEANS ╥┴═ 0).  ╚APPILY, THESE
  111. ROUTINES WORK QUITE ADMIRABLY WITH ╥┴═ 2 AND 3.  (╘O ACCESS ╥┴═ 4-7, FIDDLE
  112. BITS 4 AND 5 OF THE ══╒ ╥├╥ TO MAKE THE DESIRED ╥┴═ BLOCKS APPEAR TO THE
  113. SYSTEM AS VIRTUAL ╥┴═ 2 AND ╥┴═ 3, THEN CALL THESE ROUTINES.)  ╘HE CORE
  114. ROUTINE IS ─O┬╧P, WHICH IS SUMMARIZED BELOW [4]:
  115.  
  116. ***********************************************************************
  117. ─O┬╧P=$C2EC:  ├OPY/VERIFY MEMORY BETWEEN ╥┴═ BLOCKS ON THE ├-128.
  118.  
  119. ╨ASS:
  120.    R0   : ┴──╥1 - ADDRESS OF FIRST ("SOURCE") MEMORY RANGE
  121.    R1   : ┴──╥2 - ADDRESS OF SECOND ("DESTINATION") MEMORY RANGE
  122.    R2   : ├╧╒╬╘ - NUMBER OF BYTES TO OPERATE ON
  123.    R3╠  : ┴1┬┴╬╦ - BANK OF ┴──╥1 (E.G. 1=╞RONT╥┴═, 0=┬ACK╥┴═)
  124.    R3╚  : ┴2┬┴╬╦ - BANK OF ┴──╥2
  125.    Y    : ═╧─┼ - OPERATION TO PERFORM
  126.  
  127.  
  128. ╥ETURNS: R0-R3 UNCHANGED
  129.  
  130.   WHEN VERIFYING: X=$00 IF TWO RANGES MATCH, X=$FF IF THEY DON'T MATCH
  131.  
  132.  
  133. ─ESTROYS: A,X,Y
  134.  
  135.  
  136. ╘HE OPERATION MODE IS PASSED IN Y AS FOLLOWS:
  137.  
  138.         BIT0  BIT1   ─ESCRIPTION
  139.         ----  ----   -----------
  140.          0     0      ═OVE FROM MEMORY AT ┴──╥1 TO MEMORY AT ┴──╥2
  141.          0     1      ═OVE FROM MEMORY AT ┴──╥2 TO MEMORY AT ┴──╥1
  142.          1     0      ╙WAP MEMORY AT ┴──╥1 AND ┴──╥2
  143.          1     1      ╓ERIFY (COMPARE) MEMORY AT ┴──╥1 AND ┴──╥2
  144. ***********************************************************************
  145.  
  146. (R0, R1, ETC. ARE ALL THE STANDARD ┬╙╫ SYMBOLS DEFINED IN THE ╧FFICIAL ╟┼╧╙
  147. ╨ROGRAMMER'S ╥EFERENCE ╟UIDE [5], AND THAT COME IN THE FILE GEOS╙YM WITH
  148. GEO╨ROGRAMMER.)
  149.  
  150. ╘HERE ARE A NUMBER OF ADDITIONAL ROUTINES WHICH ARE ALSO PROVIDED FOR
  151. PROGRAMMER CONVENIENCE WHICH AUTOMATICALLY SET THE ═╧─┼ IN THE Y REGISTER FOR
  152. YOU.  ╔N ALL OF THESE ROUTINES, R0-R3 HAVE THE SAME MEANING AS THEY DO IN
  153. ─O┬╧P.
  154.  
  155. ╥OUTINE     ┴DDRESS  ═╧─┼   ─ESCRIPTION
  156. -------     -------  ----   -----------
  157. ═OVE┬─ATA    $C2E3    00    ├OPY DATA AT ┴──╥1 TO ┴──╥2
  158. ╙WAP┬─ATA    $C2E6    10    ╙WAP DATA BETWEEN ┴──╥1 AND ┴──╥2
  159. ╓ERIFY┬─ATA  $C2E9    11    ├OMPARE DATA AT ┴──╥1 AND ┴──╥2
  160.  
  161. ╔ HAVE WRITTEN A SHORT DEMONSTRATION PROGRAM WHICH SHOWS THE USE OF ═OVE┬─ATA
  162. AND ╓ERIFY┬─ATA.  ╘HE FULL SOURCE TO THIS PROGRAM, ┬═OVER, IS AVAILABLE
  163. THROUGH ANONYMOUS FTP AT TYBALT.CALTECH.EDU (IN THE RKNOP/HACKING.MAG
  164. DIRECTORY) AS WELL AS ELSEWHERE.  ╔F YOU CAN'T FIND IT, CONTACT ME (ADDRESSES
  165. ARE BELOW).  ╘HE SOURCE IS GEO╨ROGRAMMER CODE, IN GEO╫RITE 2.1 FORMAT.  ┴LL OF
  166. THE FILES YOU NEED (EXCEPT GEOS╙YM AND GEOS═AC, WHICH COME WITH GEO╨ROGRAMMER)
  167. ARE IN THE BMOVER.SFX ARCHIVE.
  168.  
  169. ╘HE FIRST FUNCTION OF ┬═OVER REPEATEDLY COPIES A SINGLE BLOCK ON ╥┴═ 1 TO
  170. SUCCESSIVE PARTS IN MEMORY IN ANY OTHER SPECIFIED BANK.  ╘HE DESTINATION BANK,
  171. DESTINATION ADDRESSES, SIZE OF THE BLOCK TO MOVE, AND NUMBER OF TIMES TO COPY
  172. IT ARE ALL SET IN CONSTANTS FOUND AT THE BEGINNING OF THE SOURCE FILE ┬═OV┴SM.
  173. ╧NCE THE MOVES (WHICH USE ═OVE┬─ATA) HAVE ALL BEEN PERFORMED, ┬═OVER USES
  174. ╓ERIFY┬─ATA TO MAKE SURE THAT ALL OF THE BLOCKS WERE COPIED SUCCESFULLY.
  175.  
  176. ╞OR INFORMATIONAL PURPOSES, ┬═OVER REPORTS THE AMOUNT OF TIME (IN TENTHS OF
  177. SECONDS) IT TOOK TO PERFORM ALL OF THE MOVES.  (╞OR THIS, ╔ USE THE ├╔┴ #1 ╘╧─
  178. CLOCK, SAVING ITS VALUE AT THE BEGINNING AND END OF THE MOVE, AND SUBTRACTING
  179. TO GET THE DIFFERENCE.)  ╔ RAN A TRIAL WHERE ╔ COPIED AN 8╦ BLOCK OF MEMORY TO
  180. ╥┴═ 2 7 TIMES (THUS FILLING 56╦ OF ╥┴═ 2).  ╘HESE MOVES TOGETHER TOOK 1 SECOND
  181. AT 2 ═╚Z, AND 2.2 SECONDS AT 1 ═HZ.  56╦/SECOND MAY BE NO ─═┴, BUT IT'S FASTER
  182. THAN A BURST LOAD!
  183.  
  184.  
  185. ╔╓. ┼XECUTING ╥OUTINES ╔N ╧THER ┬ANKS
  186.  
  187. ╙O, YOU'VE WRITTEN AN OBJECT ORIENTED DRAWING PROGRAM THAT STORES ITS LIST OF
  188. OBJECTS (32 BYTE RECORDS) IN ╥┴═ 2.  ╧R, YOU HAVE A DATABASE THAT HAS RECORDS
  189. IN ╥┴═ 0.  ┘OU WANT TO DELETE ONE RECORD AT THE BEGINNING OF THE LIST, WHICH
  190. MEANS MOVING ALL OF THE SUBSEQUENT RECORDS DOWN OVER THE MEMORY FREED UP BY
  191. THE DELETION.  ╘HERE ARE A FEW THINGS YOU CAN DO.  ╧NE, YOU CAN USE ├RAIG
  192. ┬RUCE'S DYNAMIC MEMORY ALLOCATION ROUTINES (HIGHLY RECOMMENDED).  ╘WO, YOU CAN
  193. REPEATED DO ═OVE┬─ATA TO MOVE MEMORY FROM ╥┴═ 2 (OR 0) TO A BUFFER IN ╞RONT╥┴═
  194. AND BACK.  ╧R, YOU CAN WRITE A SHORT MOVER ROUTINE IN THE ╥┴═ BANK WHERE ALL
  195. THE MOVING IS GOING TO HAPPEN.
  196.  
  197. ╘HIS IS JUST AN EXAMPLE.  ╧NE CAN VISUALIZE OTHER REASONS FOR CALLING ROUTINES
  198. IN OTHER ╥┴═ BANKS (WHAT ╔ CALL "EXTRABANKAL ROUTINES").  ╘HERE EXIST NO ╟┼╧╙
  199. ╦ERNAL ROUTINES FOR CALLING EXTRABANKAL ROUTINES.  ┴DDITIONALLY, SINCE YOUR
  200. MAIN APPLICATION MEMORY IS IN ╥┴═ 1, YOU ARE INABLE TO USE THE 128 ╦ERNAL'S
  201. ╩╙╥╞┴╥ (WHICH RETURNS YOU TO ┬ANK 15).  ╙O, WE ARE LEFT WITH IMPLEMENTING OUR
  202. OWN ╩╙╥╞┴╥.
  203.  
  204. ╟┼╧╙128 NORMALLY OPERATES WITH ╬╧ COMMON MEMORY ENABLED.  ╘HANKS TO ONE OF THE
  205. LESS WELL-KNOWN FEATURES OF THE ══╒, THERE IS NO NEED TO ENABLE COMMON MEMORY.
  206. ╘HE ══╒ ZERO PAGE REGISTERS ($D507 AND $D508) ALLOW YOU TO LOCATE THE ZERO
  207. PAGE THAT THE PROCESSOR SEES ANYWHERE IN ╥┴═ 0 OR ╥┴═ 1.  ╫HAT THIS MEANS IS,
  208. NO MATTER WHAT YOUR MEMORY CONFIGURATION IS, THE PROCESSOR SEES ZERO PAGE IN
  209. THE ╥┴═ BLOCK SPECIFIED IN $D508.  (╒NLESS YOU HAVE COMMON MEMORY ENABLE, IN
  210. WHICH CASE IT IS NOT A GOOD IDEA TO PUT ┌╨ IN ╥┴═ BLOCKS OTHER THAN ╥┴═ 0
  211. [6,7].)  ╙O, ZERO PAGE IS EFFECTIVELY COMMON MEMORY!
  212.  
  213. ╘HIS PROVIDES FOR THE POSSIBLITY OF COPYING TO ZERO PAGE A SHORT "SWITCHBOARD"
  214. ROUTINE, BASICALLY A REIMPLEMENTATION OF ╩╙╥╞┴╥, WHICH CONFIGURES THE SYSTEM
  215. FOR THE DESTINATION BANK, JSR'S TO A ROUTINE, RECONFIGURES THE SYSTEM FOR THE
  216. CALLING BANK, AND RTS'S.
  217.  
  218. ╔ ALSO DEMONSTRATE THIS TECHNIQUE IN ┬═OVER.  ╘HE SECOND FUNCTION OF ┬═OVER
  219. FIRST USES ═OVE┬─ATA TO COPY A ROUTINE TO $2000 IN ─┼╙╘┬┴╬╦ (WHICH IS SET
  220. RIGHT NOW IN THE SOURCE CODE TO ╥┴═ 0).  ╔T THEN COPIES THE ROUTINE ┌╨╩╙╥ TO
  221. $02, WHICH STORES ─┼╙╘├╞╟ IN $FF00 AND JSR'S TO $2000.  ╘HE ROUTINE AT $2000
  222. MOVES SOME DATA AROUND IN ─┼╙╘┬┴╬╦.  ╧NCE ┌╨╩╙╥ HAS RETURNED THE PROGRAM FLOW
  223. TO ╞RONT╥┴═, ┬═OVER CALLS ╓ERIFY┬─ATA TO MAKE SURE EVERYTHING WORKED.
  224.  
  225. ╫HILE MESSING AROUND IN DIFFERENT BANKS, TO BE SAFE ╔ DISSABLE ╔╥╤ INTERRUPTS.
  226. ╧N A RELATED NOTE, GEO─EBUGGER 2.0 SEEMS TO HAVE PROBLEMS WITH PROGRAMS
  227. MESSING AROUND WITH DIFFERENT BANKS.  ╔T IS NOT SURPRISING THAT THE ┬ACK╥┴═
  228. DEBUGGER (WHICH LOCATES ITSELF IN ╥┴═ 0) WOULD HAVE TROUBLE WITH PROGRAMS THAT
  229. TRIED TO USE ╥┴═ 0, BUT IT ALSO HAS TROUBLE WITH PROGRAMS THAT TRY TO USE ╥┴═
  230. 2 AND 3.  ╘HIS IS TRUE EVEN WHEN ONE USES THE SYSTEM ROUTINE ═OVE┬─ATA.  (╔
  231. FOUND THAT ╔ WAS SOMETIMES ABLE TO MAKE IT PAST A CALL TO ═OVE┬─ATA WHILE IN
  232. THE DEBUGGER, BUT THAT MORE OFTEN THE SYSTEM WOULD HANG.  ╘HIS IS ALL PROBABLY
  233. AN INTERRUPT-RELATED ISSUE.)
  234.  
  235. ╔F ONE IS TO BE REALLY CLASSY, ONE DOESN'T ACTUALLY HAVE TO COPY THE ┌╨╩╙╥
  236. ROUTINE TO ZERO PAGE.  ╧NE COULD ASSEMBLE THE APPLICATION SUCH THAT ┌╨╩╙╥ FELL
  237. TO A KNOWN OFFSET FROM A PAGE BOUNDRY; THEN, USE THE ══╒ TO POINT ZERO PAGE TO
  238. THE PAGE CONTAING ┌╨╩╙╥.  ╒NFORTUNATELY, THIS TECHNIQUE DID NOT WORK ON MY
  239. 512╦ EXPANDED 128.  ╘HE ONE INCOMPATILITY ╔ HAVE FOUND IS THAT WITH THE 512╦
  240. MODIFICATION ENABLED (╔ DO HAVE A SWITCH TO DISABLE IT, DON'T WORRY), THE ══╒
  241. FAILS TO CORRECTLY SEE ZERO PAGE IN ╥┴═ 1 WHEN REQUESTED TO.  ╥ICHARD ├URCIO
  242. EXPERIMENTED WITH IT, AND IT SEEMS THAT WHEN YOU TRY TO RELOCATE ZERO PAGE TO
  243. A PAGE IN ╥┴═ 1, IT IS ACTUALLY SEEN IN ╥┴═ 3.  ╔T IS NOT YET CLEAR WHETHER
  244. THIS IS A PROBLEM WITH THE 256╦/512╦ MODIFICATION, OR IF THE ══╒ IN A STOCK
  245. 128 JUST RELOCATES ┌╨ TO ╥┴═ 3 FIGURING THAT ╥┴═ 3 = ╥┴═ 1 (WHICH IS TRUE ON A
  246. STOCK 128, BUT NOT ON A 256╦ EXPANDED 128!)
  247.  
  248.  
  249.  
  250. ┴NYONE WHO WANTS TO GET AHOLD OF THE ┬═OVER SOURCE, OR WHO HAS OTHER
  251. QUESTIONS/COMMENTS/FLAMES CAN CONTACT ME, ╥OBERT ╦NOP, AT THE FOLLOWING
  252. ADDRESSES:
  253.  
  254. ╔NTER╬ET: RKNOP@TYBALT.CALTECH.EDU
  255. ╟┼NIE:    ╥.╦╬╧╨1
  256. ╒.╙. ═AIL:  ╥OBERT ╦NOP
  257.             123 ╙. ├HESTER #3
  258.             ╨ASADENA, ├┴  91106
  259.  
  260.  
  261. ╓. ╥EFERENCES
  262.  
  263. [1] ╫ILLIAM ├OLEMAN, 1989: "╔NSIDE ╟┼╧╙ 128"  _╘HE_╘RANSACTOR_ 9(4), P. 29.
  264.  
  265. [2] ╥ICHARD ├URCIO, 1991: "┼XPANDING THE 128 ╨ART ╧NE: 256╦" _╘WIN_├ITIES_128_
  266. #30, P. 7.
  267.  
  268. [3] ╥ICHARD ├URCIO, 1992: "┼XPANDING THE 128 ╨ART ╘WO: 4 ═ODE 512╦"
  269. _╘WIN_├ITIES_128_ #31, P. 5.
  270.  
  271. [4] ┬ERKELEY ╙OFTWORKS, 1988: _╘HE_╚ITCHHIKER'S_╟UIDE_╘O_╟EOS_.
  272.  
  273. [5] ═ICHAEL ╞ARR, 1987: _╘HE_╧FFICAL_╟┼╧╙_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_.
  274. ┬ANTAM ┬OOKS, ╬EW ┘ORK/╘ORONTO.
  275.  
  276. [6] ╠ARRY ╟REENLY ET. AL, 1986: _├OMMODORE_128_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_.
  277. ┬ANTAM ┬OOKS, ╬EW ┘ORK/╘ORONTO.
  278.  
  279. [7] ╧TTIS ╥. ├OWPER, 1986: _═APPING_THE_├OMMODORE_128_.  ├OMPUTE! ╨UBLICATIONS,
  280. ╟REENSBORO, ╬├.
  281.  
  282. ==============================================================================
  283. ─┘╬┴═╔├ ═┼═╧╥┘ ┴╠╠╧├┴╘╔╧╬ ╞╧╥ ╘╚┼ 128: ┬REAKING THE 64╦ ┬ARRIER
  284.  
  285. BY ├RAIG ┬RUCE (F2RX@JUPITER.SUN.CSD.UNB.CA)
  286.  
  287. ┴LTHOUGH THIS ARTICLE WOULD BE BEST DESCRIBED AS EXTREMELY TECHINICAL, ╔ THINK
  288. THAT IT HAS SOMETHING FOR EVERYONE.  ╔T COULD ALSO BE DESCRIBED AS BEING
  289. EXTREMELY LONG.
  290.  
  291. ┬ELOW ╔ HAVE WRITTEN A PROGRAM THAT WILL READ IN THE LINES OF A FILE, SORT
  292. THEM, AND WRITE THEN BACK OUT TO ANOTHER FILE.  ┬ECAUSE OF THE NATURE OF THE
  293. PROBLEM, THE EACH LINE OF THE ENTIRE FILE MUST RESIDE IN THE MEMORY OF THE
  294. COMPUTER.  ╔ IMPLEMENT AND USE DYNAMIC MEMORY ALLOCATION SUCH THAT THE FILE TO
  295. BE SORTED CAN BE LARGER THAN 64╦, AND ╔ USE A DYNAMIC DATA STRUCTURE SUCH THAT
  296. THE MEMORY IS USED VERY EFFICIENTLY.  ╘HE MEMORY ROUTINES WERE EXTRACTED FROM
  297. A TEXT EDITOR CALLED "┌ED-128" WHICH ALSO BREAKS THE 64╦ BARRIER AND CAN EDIT
  298. SOME HUMONGOUS FILES (AND VERY EFFICIENTLY TOO).  ┴LTHOUGH IMPLEMENTED FOR THE
  299. ├-128, THE DYNAMIC MEMORY SCHEME COULD ALSO BE FAIRLY EASILY (IE. IN A SINGLE
  300. LIFETIME) PORTED TO THE ├-64.
  301.  
  302. ------------------------------------------------------------------------------
  303.  
  304. 1. ╔╬╘╥╧─╒├╘╔╧╬
  305.  
  306. ╚OW MANY OF US ARE SICK AND TIRED OF THE "64╦ LIMIT" THAT MANY PROGRAMS FOR
  307. THE 128 AND 64 SEEM TO HAVE?  ═ANY TERMINAL PROGRAMS, TEXT EDITORS, AND EVEN
  308. FILE COPIERS SEEM TO BE AFFLICTED WITH THIS PROBLEM.  ┴NOTHER PROBLEM IS THAT
  309. PROGRAMS OFTEN RESERVE LARGE SECTIONS OF MEMORY FOR SPECIFIC PURPOSES (SUCH AS
  310. THE KILL BUFFER OF A TEXT EDITOR) AND CANNOT RECONFIGURE THEMSELVES (VERY
  311. EASILY) FOR DIFFERENT DEMANDS.  ╙TILL ANOTHER PROBLEM IS THAT MANY PROGRAMS DO
  312. NOT MAKE USE OF A ╥AM ┼XPANSION ╒NIT (IF YOU ARE FORTUNATE ENOUGH TO HAVE ONE)
  313. TO STORE YOUR VOLUMNOUS USER DATA.
  314.  
  315. ╘HE WAY TO OVERCOME THE LIMITATIONS OF THE 64╦ ARCHITECTURE OF THE ├128 AND
  316. ├64 IS TO USE DYNAMICALLY ALLOCATED MEMORY.  ╫HAT THIS MEANS IS THAT
  317. INITIALLY, ALL OF THE MEMORY OF THE COMPUTER IS FREE AND WHEN A USER PROGRAM
  318. REQUIRES SOME MEMORY TO STORE USER DATA, IT CALLS A SPECIAL SUBROUTINE THAT
  319. ALLOCATES A GIVEN NUMBER OF BYTES OF MEMORY TO THE PROGRAM TO STORE THE USER
  320. DATA.  ┴ND WHEN THE PROGRAM IS FINISHED USING THAT CHUNK OF MEMORY, IT CALLS A
  321. SPECIAL SUBROUTINE TO FREE THE MEMORY CHUNK AND MAKE IT AVAILABLE FOR FUTURE
  322. ALLOCATE REQUESTS.
  323.  
  324. ╧NE COMPLICATION OF THIS MEMORY USAGE SCHEME IS THAT A PROGRAM HAS TO KEEP
  325. TRACK OF WHICH CHUNKS OF MEMORY IT USES FOR WHAT.  ╘HIS IS WHERE DYNAMIC DATA
  326. STRUCTURES COME IN.  ╘HE MOST IMPORTANT CONCEPT HERE IS A POINTER.  ┴ POINTER
  327. IS SIMPLY A VARIABLE THAT STORES THE ADDRESS OF SOME DATA STRUCTURE (IE. SOME
  328. CHUNK OF MEMORY).  ╔F WE KNOW THE ADDRESS OF A DATA STRUCTURE, THEN WE CAN
  329. READ IT AND MODIFY IT.
  330.  
  331. ╘O OVERCOME THE PROBLEM OF NOT KNOWING HOW MANY RECORDS WILL NEED TO BE
  332. STORED, RECORDS ARE OFTEN STORED IN LISTS, WHERE EVERY RECORD CONTAINS A
  333. POINTER TO THE NEXT RECORD IN THE LIST, EXCEPT FOR THE LAST ONE, WHICH
  334. CONTAINS A SPECIAL VALUE THAT COULD NOT BE MISTAKEN FOR AN ORDINARY POINTER
  335. (IT IS CALLED THE ╬ULL (OR ╬IL FOR YOU ╨ASCALERS) POINTER).  ╘HUS, IF WE KNOW
  336. THE ADDRESS OF THE FIRST RECORD (BY USING A "HEAD POINTER"), THEN WE HAVE
  337. SEQUENTIAL ACCESS TO ALL OF THE RECORDS IN THE LIST.  ╔F WE WANT TO ADD OR
  338. DELETE RECORDS FROM THE LIST, THEN WE MUST MODIFY THE OTHER POINTERS SUCH THAT
  339. THE CONSISTENCY OF THE LIST IS MAINTAINED.  ╧RGANIZATIONS OTHER THAN SIMPLE
  340. LISTS ARE ALSO POSSIBLE.
  341.  
  342. ╘HE IMPLEMENTATION HERE IS ABLE TO ALLOCATE ╥┴═0 MEMORY FOR STORING USER DATA
  343. RECORDS, AS WELL AS ╥┴═1 MEMORY AND EVEN ╥┼╒ MEMORY.  ┴S LONG AS THE
  344. APPLICATION PROGRAM KEEPS TRACK OF THE POINTERS TO ITS RECORDS, LARGE VOLUMES
  345. OF USER DATA CAN BE STORED SINCE IT WILL BE DISTRIBUTED AMONG ALL OF THE
  346. MEMORY THAT IS AVAILABLE FROM BOTH THE INTERNAL MEMORY BANKS AND THE EXTERNAL
  347. MEMORY BANKS, THUS BREAKING THE 64╦ BARRIER.
  348.  
  349. ------------------------------------------------------------------------------
  350.  
  351. 2. ╞╧╥ ╘╚┼ ╬╧╓╔├┼ ╚┴├╦┼╥
  352.  
  353. ┘OU GET A SORTING UTILITY PROGRAM.  ╘HIS PROGRAM IMPLEMENTS THE INSERTION SORT
  354. ALGORITHM, SO DON'T EXPECT TO BREAK ANY SPEED RECORDS.  ┴LSO, THE WAY THAT
  355. DYNAMIC MEMORY IS IMPLEMENTED HERE IS MORE SUITED FOR LARGE DATA STRUCTURES
  356. THAT WILL ONLY BE ACCESSED SLOWLY AND INFREQUENTLY (SUCH AS THE CURRENT
  357. DOCUMENT IN A TEXT EDITOR); HOWEVER, ╔ WANTED TO COME UP WITH A USEFUL UTILITY
  358. AND ╔ HAVE NEVER HEARD OF A GENERAL FILE SORTER FOR THE 128 OR 64.  ╘HE
  359. INSERTION SORT DOES, HOWEVER, LEND ITSELF WELL TO BEING USED WITH DYNAMIC DATA
  360. STRUCTURES IN GENERAL, SINCE YOU DON'T ACTUALLY HAVE TO MOVE ANYTHING; YOU
  361. JUST CHANGE A COUPLE OF POINTERS IN ORDER TO INSERT A LINE (RECORD) BETWEEN
  362. TWO OTHER LINES.  ┴LSO, IT TURNS OUT THE THE INSERTION SORT IS QUITE EFFICIENT
  363. IF YOUR INPUT FILE IS ALREADY MOSTLY OR PARTIALLY SORTED.
  364.  
  365. ╘HE SORT UTILITY ITSELF IS COMPLETELY MACHINE LANGUAGE BUT ASSUMES THAT THE
  366. INPUT AND OUTPUT FILES ARE ALREADY OPENED, SO A ┬┴╙╔├ DRIVER PROGRAM IS
  367. REQUIRED TO SET THINGS UP TO AND ALLOW THE USER TO EASILY CHANGE THE SORTING
  368. PARAMETERS.  ╙UCH A PROGRAM IS LISTED HERE:
  369.  
  370.  1 I$="INPUTFILE.TXT" : ID=8 : SF=1
  371.  2 O$="OUTPUTFILE.TXT" : OD=8
  372.  3 :
  373.  100 PRINT"LOADING SORT.BIN..."
  374.  110 BANK 15
  375.  120 BLOAD"SORT.BIN",U(ID)
  376.  130 PRINT"SCRATCHING OLD FILE..."
  377.  140 SCRATCH(O$),U(OD)
  378.  150 PRINT"SORTING..."
  379.  160 OPEN1,ID,2,"0:"+I$
  380.  170 OPEN2,OD,3,"0:"+O$+",S,W"
  381.  180 SYS DEC("1300"),SF
  382.  190 CLOSE2
  383.  200 CLOSE1
  384.  210 PRINT"FINISHED!"
  385.  
  386. ╠INES 1 AND 2 SET UP THE SORTING PARAMETERS: THE INPUT AND OUTPUT FILENAMES,
  387. THE INPUT AND OUTPUT FILE DEVICE NUMBERS, AND THE SORTING FIELD POSITION.
  388. ├HANGE THE "SF" VALUE TO THE POSITION OF THE FIRST CHARACTER OF THE KEY
  389. FIELD.  ╘HE FIRST POSITION ON THE LINE IS 1 (NOT 0).  (╘HIS CORRESPONDS TO
  390. WHAT ┌ED USES FOR COLUMNS).  ╙TARTING FROM THAT POSITION, THE REST OF THE LINE
  391. IS USED FOR THE COMPARISON THAT DETERMINES THE ORDER OF THE LINES.  ╔F A LINE
  392. IS ENCOUNTERED THAT IS SHORTER THAN THE POSITION OF THE SORTING FIELD, THE KEY
  393. VALUE IS TAKEN TO BE THE ╬ULL ╙TRING (WHICH COMES BEFORE ANY OTHER STRING).
  394.  
  395. ╘HE PROGRAM CONTINUES TO LOAD IN THE MACHINE LANGUAGE (WHICH FITS INTO THE
  396. $1300 SLOT) AND SCRATCH THE OUTPUT FILE IF IT ALREADY EXISTS.  ╘HEN THE FILES
  397. ARE OPENED, MACHINE LANGUAGE IS CALLED, AND THE FILES ARE CLOSED AND THE
  398. PROGRAM EXITS.  ╫HILE READING THE FILE, THE PROGRAM WILL SPLIT ANY LINES THAT
  399. ARE LONGER THAN 242 CHARACTERS AND TREAT THEM AS MULTIPLE LINES.
  400.  
  401. ╞OR TESTED THE SORT UTILITY, ╔ USED A FILE THAT CONTAINS 1058 LINES OF THE
  402. FOLLOWING FORM:
  403.  
  404. ╥╧╪┼╘╘┼                     ═╒╙╘ ╚┴╓┼ ┬┼┼╬ ╠╧╓┼                       ┴01-1-01
  405. ┴─┴═╙, ┬╥┘┴╬                ╙╒══┼╥ ╧╞ '69                             ┴05-1-10
  406. ╩╧┼╠, ┬╔╠╠┘                 ╨╥┼╙╙╒╥┼                                  ═11-1-07
  407. ┼┴╟╠┼╙                      ╬┼╫ ╦╔─ ╔╬ ╘╧╫╬                           ╥06-2-04
  408. ┼╠┼├╘╥╔├ ╠╔╟╚╘ ╧╥├╚┼╙╘╥┴    ├┴╠╠╔╬╟ ┴═┼╥╔├┴                           ╥11-1-05
  409. ├╧├╦┬╒╥╬, ┬╥╒├┼             ╫╧╬─┼╥╔╬╟ ╫╚┼╥┼ ╘╚┼ ╠╔╧╬╙ ┴╥┼             ╥14-1-03
  410.  
  411. ┴S YOU MAY GUESS, IT IS A TAPE LIBRARY.  ╘HE FILE IS 83╦ IN LENGTH.  ╔ SORTED
  412. IT ON BOTH MY 1581 (WITH ╩IFFY─╧╙) AND MY ╥AM╠INK AND THEN ╔ SORTED AGAIN THE
  413. FILE THAT ╔ SORTED IN THE FIRST PLACE.  ╘HE RESULTING EXECUTION TIMES ARE AS
  414. FOLLOWS:
  415.  
  416.     ╫╔╘╚ ┼╪╨┴╬╙╔╧╬ ═┼═╧╥┘                ╫╔╘╚╧╒╘ ┼╪╨┴╬╙╔╧╬ ═┼═╧╥┘
  417.  
  418.  ╥AMLINK REGULAR = 110 SECONDS         ╥AMLINK REGULAR = 376 SECONDS
  419.  ╥AMLINK SORTED  =  20 SECONDS         ╥AMLINK SORTED  =  24 SECONDS
  420.  1581 REGULAR    = 120 SECONDS         1581 REGULAR    = 397 SECONDS
  421.  1581 SORTED     =  33 SECONDS         1581 SORTED     =  55 SECONDS
  422.  
  423. ┘OU'LL NOTE THAT HAVING EXPANSION MEMORY MAKES SORT OPERATE FASTER.  ╘HIS IS
  424. BECAUSE THE ╥┼╒ ├ONTROLLER CAN TRANSFER DATA AROUND FASTER THAN THE ├╨╒ CAN.
  425. ╘HE EFFECT IS EVEN MORE PRONOUNCED WHEN USING RECORDS LONGER THAN 78-CHARACTER
  426. LINES OF TEXT.  ╘HIS IS WHY IT IS SENSIBLE TO USE EXPANSION MEMORY FOR GENERAL
  427. DATA STORAGE AND ACCESSING.  ╘HE REASON WHY THE EXECUTION TIMES ARE SO LONG IS
  428. THAT APPROXIMATELY 1058*529/2 = 280,000 "FAR MEMORY" LINE-LENGTH FETCHES HAVE
  429. TO TAKE PLACE, ALONG WITH THAT NUMBER OF "ZPLOAD"S AND STRING COMPARISONS, AND
  430. 1058 "MALLOC"S AND "FREE"S.  ┴LSO, WE ALL KNOW THAT THE ├OMMODORE FILE READING
  431. AND WRITING MECHANISMS ARE NOT SEVERELY SWIFT.
  432.  
  433. ------------------------------------------------------------------------------
  434.  
  435. 3. ╞╧╥ ╘╚┼ ╔╬╘┼╥═┼─╔┴╘┼ ╚┴├╦┼╥
  436.  
  437. ┘OU GET A DYNAMIC MEMORY ALLOCATION AND USAGE PACKAGE THAT CAN BE INCORPORATED
  438. INTO YOUR OWN PROGRAMS.
  439.  
  440. 3.1. ═┼═╧╥┘ ╨┴├╦┴╟┼ ├┴╠╠╙
  441.  
  442. ╘HE PACKAGE INCLUDES EIGHT SYSTEM CALLS:
  443.  
  444.  STARTUP ()
  445.  SHUTDOWN()
  446.  ZPLOAD  ( [ZP1]=╞AR╨OINTER, .╪=┌P┴DDR, .┘=╠ENGTH )
  447.  ZPSTORE ( [ZP1]=╞AR╨OINTER, .╪=┌P┴DDR, .┘=╠ENGTH )
  448.  FETCH   ( [ZP1]=╞AR╨OINTER, (ZW1)=╥AM0POINTER, .┴┘=╠ENGTH )
  449.  STASH   ( [ZP1]=╞AR╨OINTER, (ZW1)=╥AM0POINTER, .┴┘=╠ENGTH )
  450.  MALLOC  ( .┴┘=╠ENGTH ) : [ZP1]=╞AR╨OINTER, .├╙=ERROR
  451.  FREE    ( [ZP1]=╞AR╨OINTER, .┴┘=╠ENGTH ) : .├╙=ERROR
  452.  
  453. ╘HE "(...)" MEANS INPUT PARAMETERS AND ":" PRECEEDS OUTPUT PARAMETERS.  ".╪"
  454. AND ".┘" REFER TO THE PROCESSOR REGISTERS AND ".┴┘" MEANS THE 16-BIT VALUE
  455. WITH THE .┴ REGISTER HOLDING THE LOW BYTE AND THE .┘ REGISTER HOLDING THE HIGH
  456. BYTE.  ╫ITH "(ZW1)" ╔ AM REFERING TO THE INDIRECT POINTER IN THE ZERO PAGE
  457. LOCATIONS "ZW1" (LOW BYTE) AND "ZW1+1" (HIGH BYTE) ("ZW" MEANS ZERO PAGE WORD
  458. AND IT IS ASSIGNED TO LOCATIONS $╞┼ TO $╞╞) AND WITH "[ZP1]" ╔ AM REFERING TO
  459. THE THREE BYTE POINTER VALUE IN LOCATIONS "ZP1" (ADDRESS LOW BYTE), "ZP1+1"
  460. (ADDRESS HIGH BYTE), AND "ZP1+2" (BANK NUMBER BYTE) ("ZP" MEANS ZERO PAGE
  461. POINTER AND IT IS ASSIGNED TO ADDRESSES $╞┴ TO $╞├).  ╘HIS THREE-BYTE POINTER
  462. IS REFERED TO AS A "╞AR ╨OINTER".  ╘HE ".├╙=ERROR" MEANS THAT IF THE ROUTINE
  463. RETURNS WITH THE CARRY FLAG SET, AN ERROR HAS OCCURED.  ╘HE ONLY POSSIBLE
  464. ERROR RETURN IN THIS PACKAGE IS IF MALLOC CANNOT FIND ENOUGH CONTIGUOUS FREE
  465. MEMORY TO SATISFY YOUR REQUEST.
  466.  
  467. ┘OU DO NOT ACTUALLY HAVE TO KNOW WHAT THE BANK NUMBERS MEAN SINCE THEY ARE
  468. GENERATED AND USED BY THE PACKAGE AS AN OPAQUE DATA TYPE (PARLEZ-VOUS
  469. ═ODULA-2?), BUT HERE IS WHAT THEY MEAN ANYWAY.  ┴ VALUE OF $3╞ MEANS INTERNAL
  470. BANK ╥┴═0 AND A VALUE OF $7╞ MEANS INTERNAL BANK ╥┴═1.  ╘HIS WORKS OUT
  471. CONVENIENTLY IN THE IMPLEMENTATION, SINCE THESE ARE THE ══╒ CONFIGURATION
  472. REGISTER VALUES FOR THOSE TWO BANKS.  ┴ VALUE FROM $80 TO $╞┼ REFERS TO AN
  473. EXPANSION (╥┼╒) MEMORY BANK.  $80 MEANS EXPANSION BANK0, $81 BANK1, ETC.  ╘HIS
  474. MEANS THAT THE PACKAGE CAN SUPPORT UP TO 8 ═EGS (MINUS 64╦) OF EXPANSION
  475. MEMORY (AND IT DOES).  ╘HESE VALUES ARE CONVENIENT TO USE SINCE AFTER LOADING
  476. THE BANK NUMBER INTO A REGISTER, THE ╬EGATIVE FLAG OF THE PROCESSOR WILL BE
  477. SET (USEFUL IF HANDLING EXPANSION MEMORY IS A SPECIAL CASE), AND THIS VALUE
  478. CAN BE PUT DIRECTLY INTO THE ╥┼╒ ├ONTROLLER'S BANK REGISTER.  ╔ DON'T THINK
  479. YOU HAVE TO WORRY ABOUT HAVING THE HIGH BIT BE A "1" SINCE IT IS DONE
  480. CONSISTENTLY AND ╔ HAVE NEVER HEARD OF AN ╥┼╒ LARGER THAN 2 ═EGS.  ┴ BANK
  481. VALUE OF $╞╞ IS USED TO REPRESENT THE ╬ULL POINTER.
  482.  
  483. ╘HE "STARTUP" ROUTINE INSTALLS THE COMMON CODE, DETERMINES THE SIZE OF YOUR
  484. ╥┼╒, AND INITIALIZES THE DYNAMIC MEMORY ALLOCATION MECHANISM.  ╔N ORDER FOR
  485. THE PACKAGE TO ACCESS INTERNAL MEMORY BANK ╥┴═1, IT HAS TO CALL A ROUTINE THAT
  486. IS IN MEMORY BELOW ADDRESS $0400.  ╙INCE THE PACKAGE STARTS AT $1300, IT HAS
  487. TO COPY A FEW "COMMON CODE" SUBROUTINES INTO LOW MEMORY SUCH THAT IT CAN CALL
  488. THEM LATER.  ╘HE COMMON CODE IS INSTALLED AT ADDRESS $0200, THE ┬┴╙╔├ INPUT
  489. BUFFER.  ─ON'T OVERWRITE THIS AREA WHILE THE PACKAGE IS IN USE.  ╘HE "SNIFF"
  490. ROUTINE IS CALLED TO DETERMINE THE NUMBER OF BANKS THAT YOUR ╥┼╒ HAS.  ┌ERO
  491. BANKS MEANS THAT YOU HAVE NO ╥┼╒.  ╫HILE SNIFFING, THE PACKAGE OVERWRITES THE
  492. FIRST FOUR BYTES OF EVERY EXISTING EXPANSION BANK (UNLESS YOU LIMIT THE NUMBER
  493. OF EXPANSION BANKS THAT THE PACKAGE IS ALLOWED TO USE).  ╘O INITIALIZE THE
  494. DYNAMIC MEMORY ALLOCATION, THE "FREE" ROUTINE IS CALLED FOR ╥┴═0, ╥┴═1, AND
  495. EACH EXPANSION BANK.  ╥┴═0 FROM $4000 TO THE TOP OF ┬┴╙╔├ MEMORY ($╞┼╞╞) IS
  496. FREED, ╥┴═1 FROM $0400 TO $╞┼╞╞ IS FREED, AND ALL EXPANSION BANKS ARE FREED
  497. BETWEEN ADDRESSES $0000 TO $╞╞╞7.  ╘HUS, IF YOU HAVE NO EXPANSION MEMORY, YOU
  498. GET ABOUT 110╦ FREE AND IF YOU HAVE A 512╦ EXPANDER, YOU GET ABOUT 620╦ FREE.
  499.  
  500. ╘HE "SHUTDOWN" ROUTINE DOESN'T ACTUALLY HAVE VERY MUCH TO DO.  ┬ASICALLY, IT
  501. JUST ZEROS OUT THE COMMON CODE.  ╔ DID THIS SO IF YOU CALLED THE SORT ROUTINE
  502. FROM ┬┴╙╔├ DIRECT INPUT MODE, YOU WOULD NOT GET A "SYNTAX ERROR" FROM ┬┴╙╔├
  503. TRYING TO INTERPRET THE GARBAGE LEFT BEHIND.  ╬OW, WHEN ┬┴╙╔├ ENCOUNTERS A
  504. ZERO, IT STOPS INTERPRETING.
  505.  
  506. ╘HE "ZPLOAD" ROUTINE WILL LOAD THE GIVEN NUMBER OF BYTES INTO ZERO PAGE
  507. STARTING AT THE GIVEN ZERO PAGE ADDRESS, FROM ANY FAR POINTER ADDRESS.  ╔T
  508. DOESN'T MATTER WHETHER THE FAR ADDRESS IS IN INTERNAL OR EXPANSION MEMORY; THE
  509. OPERATION IS THE SAME.  ╘HIS IS THE LEVEL OF SOFTWARE THAT MAKES ACCESSING THE
  510. DIFFERENT TYPES OF MEMORY TRANSPARENT TO THE USER.  ╘O LOAD FROM ╥┴═0, TRUE
  511. ╥┴═0 IS SWITCHED INTO CONTEXT (DID ╔ MENTION THAT THE PACKAGE IS MEANT TO
  512. EXECUTE WITH ══╒ CONFIGURATION $0┼ IN CONTEXT - THIS CONFIGURATION GIVES ╥┴═0
  513. FROM $0000 TO $┬╞╞╞, THE KERNEL ╥╧═ FROM $├000 TO $╞╞╞╞ AND THE ╔/╧ SPACE ON
  514. TOP OF THE KERNEL ╥╧═ FROM $─000 TO $─╞╞╞ - ╔ CALL THIS THE ╙┘╙ OR ╙┘╙0 BANK)
  515. AND THE TRANSFER IS DONE WITH A LOOP.  ╞OR A ZPLOAD FROM ╥┴═1, A COMMON CODE
  516. ROUTINE IS CALLED THAT SWITCHES ╥┴═1 INTO CONTEXT, COPIES IN A LOOP, AND THEN
  517. SWITCHES BACK TO ╙┘╙0.  ╞OR AN EXPANSION MEMORY POINTER, THE ╥┼╒ ├ONTROLLER
  518. REGISTERS ARE SET UP AND THE TRANSFER IS PERFORMED.  ╘HE PACKAGE WILL WORK
  519. WITH WHATEVER ┌ERO ╨AGE IS IN CONTEXT (WITH ══╒ REGISTER $─507), SINCE IT IS
  520. CONVENIENT TO USE YOUR OWN ZERO PAGE IN YOUR PROGRAMS.  ╞OR TRANSFERS OF LESS
  521. THAN ABOUT 16 BYTES, INTERNAL MEMORY IS FASTER, AND FOR LONGER TRANSFERS,
  522. EXPANSION MEMORY TURNS OUT TO BE FASTER.  ╞OR REALLY LONG TRANSFERS (SAY, 80
  523. BYTES), USING THE EXPANSION MEMORY IS ═╒├╚ FASTER (A MARGINAL COST OF ONE
  524. MICROSECOND PER BYTE AS OPPOSED TO NINE).  ╘HE "[ZP1]" PARAMETER IS UNALTERED
  525. BY THIS CALL, BUT THE REGISTER VALUES ARE QUITE CHANGED.  ╘HE "(ZW1)"
  526. PARAMETER AREA IS ALSO LEFT UNTOUCHED.
  527.  
  528. ╘HE "ZPSTORE" ROUTINE WORKS THE SAME AS "ZPLOAD" EXCEPT IT STORES TO THE FAR
  529. MEMORY FROM ZERO PAGE.
  530.  
  531. ╘HE "FETCH" ROUTINE FETCHES THE GIVEN NUMBER OF BYTES FROM A FAR ADDRESS INTO
  532. THE ╥┴═0 BANK (NOT ╙┘╙0) AT THE GIVEN ADDRESS.  ╒NLIKE THE ZERO PAGE LOAD
  533. ROUTINE, YOU CAN TRANSFER UP TO 64╦ OF MEMORY WITH THIS ROUTINE.  ┴GAIN, THE
  534. TYPE OF MEMORY TO BE FETCHED IS TRANSPARENT TO THE USER.  ╞OR AN INTERNAL
  535. MEMORY FETCH, THE TRANSFERS ARE PERFORMED IN 256 BYTE CHUNKS.  ╘HIS MAKES THE
  536. IMPLEMENTATION EASIER.  ╞OR EACH BYTE TRANSFERRED FROM ╥┴═1, ╥┴═1 IS SWITCHED
  537. IN AND THEN ╥┴═0 IS SWITCHED IN, SO THE TRANSFER IS NOT EXTREMELY EFFICIENT.
  538. ╞OR THE EXPANSION MEMORY, THE ╥┼╒ ├ONTROLLER IS SET UP AND THEN THE ENTIRE
  539. TRANSFER (UP TO 64╦) IS PERFORMED AT A RATE OF 1 ═EG/SECOND.  ╘HIS IS
  540. CONSIDERABLY FASTER THAN INTERNAL MEMORY FETCHING.  ╘HIS ROUTINE HANDLES A
  541. TRANSFER LENGTH OF 0 BYTES PROPERLY.  ╘HE "ZP1" AND "ZW1" PARAMETERS ARE
  542. RETURNED UNALTERED, BUT AGAIN, THE REGISTERS ARE SMASHED.
  543.  
  544. ╘HE "STASH" ROUTINE OPERATES THE SAME AS FETCH, EXCEPT THAT THE DATA IS
  545. TRANSFERRED FROM THE NEAR ("ZW1") ADDRESS TO THE FAR ("ZP1") ADDRESS.
  546.  
  547. ╘HE "MALLOC" ROUTINE ATTEMPTS TO FIND A CHUNK OF CONTIGUOUS MEMORY OF THE
  548. GIVEN LENGTH TO ALLOCATE TO YOU.  ╔F IT CAN FIND ONE, IT RETURNS THE FAR
  549. POINTER TO IT IN THE "[ZP1]" PARAMETER.  ╔F IT CANNOT FIND ONE, IT RETURNS
  550. WITH THE CARRY FLAG SET.  ╘HIS ROUTINE CLOBBERS THE REGISTERS.
  551.  
  552. ╘HE "FREE" ROUTINE RETURNS TO THE POOL OF FREE MEMORY THE CHUNK OF MEMORY
  553. SPECIFIED BY THE FAR POINTER AND LENGTH PARAMETERS.  ╘HIS ROUTINE CLOBBERS THE
  554. "[ZP1]" PARAMETER AND THE REGISTERS.  ╘HE CARRY FLAG IS ALWAYS CLEARED UPON
  555. RETURN, SINCE THE ROUTINE DOES NOT (CURRENTLY) CHECK FOR ANY ERRORS.
  556.  
  557. 3.2. ═┼═╧╥┘ ┴╠╠╧├┴╘┼ ┴╬─ ╞╥┼┼
  558.  
  559. ╘HE MALLOC AND FREE ROUTINES MAINTAIN A LINKED LIST OF FREE MEMORY CHUNKS.  ┴
  560. FREE MEMORY CHUNK IS DESCRIBED BY A FIVE BYTE STRUCTURE THAT IS AT THE
  561. BEGINNING OF THE CHUNK.  ╘HE FIRST THREE BYTES ARE A FAR POINTER TO THE NEXT
  562. FREE MEMORY CHUNK AND THE FOLLOWING TWO BYTES GIVE THE TOTAL LENGTH OF THE
  563. CHUNK.  ╘HE STRUCTURE IS THUS:
  564.  
  565.   +----------+----------+----------+----------+----------+---...
  566.   ▄ ╬EXT     ▄ ╬EXT     ▄ ╬EXT     ▄ ├HUNK    ▄ ├HUNK    ▄
  567.   ▄ CHUNK    ▄ CHUNK    ▄ CHUNK    ▄ LENGTH   ▄ LENGTH   ▄  GARBAGE
  568.   ▄ LOW ADDR ▄ HIGH ADDR▄ BANK NUM ▄ LOW      ▄ HIGH     ▄
  569.   +----------+----------+----------+----------+----------+---...
  570.     CHUNK+0    CHUNK+1    CHUNK+2    CHUNK+3    CHUNK+4
  571.  
  572. ┴LL OF THE FREE (AND ALLOCATED) MEMORY CHUNKS ARE ALWAYS ALIGNED ON AN EIGHT
  573. BYTE BOUNDARY.  ╘HIS GUARANTEES THAT NO MATTER WHAT HAPPENS, THERE WILL ALWAYS
  574. BE AT LEAST EIGHT BYTES AVAILABLE IN EACH FREE MEMORY CHUNK TO HOLD THE FREE
  575. CHUNK DESCRIPTOR INFORMATION.  ╘HUS, IF YOU WERE TO MAKE A REQUEST FOR THREE
  576. BYTES, THE SYSTEM WOULD GIVE YOU EIGHT, AND WHEN YOU REQUEST TO FREE THOSE
  577. THREE BYTES, THE SYSTEM WOULD AUTOMATICALLY FREE EIGHT.  ╘HIS CAN LEAD TO SOME
  578. SOME WASTED SPACE WHEN USING SMALL STRUCTURES.
  579.  
  580. ╘HE MEMORY CHUNKS ARE KEPT IN ORDER OF "INCREASING" ADDRESS.  ╔ SAY
  581. "INCREASING" BECAUSE WHILE THE CHUNKS WITHIN A BANK ARE IN INCREASING ADDRESS
  582. ORDER, THE SYSTEM CONSIDERS BANK NUMBER $87 (EXPANSION BANK 7) TO BE LOWER
  583. THAN BANK NUMBER $3╞ (╥┴═0).  ╘HIS ANOMOLY MAKES THE SYSTEM ALLOCATE ITS
  584. EXTERNAL MEMORY BEFORE ALLOCATING INTERNAL MEMORY.  ╘HIS IS GOOD SINCE
  585. EXTERNAL MEMORY GENERALLY WORKS FASTER THAN INTERNAL MEMORY.
  586.  
  587. ╘HIS MEMORY IS ALLOCATED FIRST SINCE THE MALLOC ROUTINE USES A FIRST-FIND
  588. ALGORITHM FOR SEARCHING FOR A SUFFICIENT FREE MEMORY CHUNK.  ╔T STOPS
  589. SEARCHING WHEN IT FINDS A FREE MEMORY CHUNK LARGE ENOUGH TO SATISFY THE USER'S
  590. REQUEST.  ╔F THE FREE CHUNK IS EXACTLY THE SAME SIZE AS THE REQUEST, THE FREE
  591. CHUNK IS UNLINKED FROM THE FREE CHUNK LIST AND THE POINTER IS RETURNED.  ╔F
  592. THE FREE CHUNK IS LARGER THAN THE REQUESTED SIZE, IT IS SPLIT UP.  ┴ POINTER
  593. TO THE TOP ╬ BYTES OF THE CHUNK IS RETURED TO THE USER AND THE SIZE OF THE
  594. FREE CHUNK IS REDUCED BY ╬.  ╘HE MEMORY IS ALLOCATED FROM THE TOP OF THE CHUNK
  595. MAKE IT SO NO LINKING AND UNLINKING HAS TO TAKE PLACE IN THIS CASE.
  596.  
  597. ╘HE FREE ROUTINE IS MORE COMPLICATED THAN THE ALLOCATE ROUTINE SINCE FREE HAS
  598. TO DEAL WITH MORE CASES.  ╞REE HAS TO SEARCH THROUGH THE LINKED LIST OF FREE
  599. MEMORY CHUNKS TO FIND THE TWO CHUNKS THAT STRADDLE THE CHUNK TO BE FREED.
  600. ╞REE ATTEMPTS TO COALESCE (MERGE) THE NEW CHUNK WITH THE PREVIOUS CHUNK AND
  601. WITH THE NEXT CHUNK IN ORDER TO END UP WITH THE LARGEST FREE CHUNKS THAT IT
  602. CAN UNDER THE CIRCUMSTANCES.  ╠ARGE FREE CHUNKS ARE GOOD SINCE THEY CAN BE
  603. USED FOR LARGER REQUESTS.  ╘WO CHUNKS CAN BE COALESCED IF THEY ARE
  604. SIDE-BY-SIDE IN MEMORY (ZERO BYTES APART) AND ON THE SAME BANK.  ╘O COALESCE
  605. THEM, THE SIZE OF THE FIRST ONE IS INCREASED BY THE SIZE OF THE SECOND ONE AND
  606. THE POINTER TO THE SECOND ONE IS FORGOTTEN.
  607.  
  608. ╬OTE THAT THIS SCHEME WORKS DIFFERENTLY FROM THE DYNAMIC ALLOCATION SCHEME
  609. THAT ┬┴╙╔├ USES FOR ITS STRINGS.  ┬┴╙╔├ DOES NOT ATTEMPT TO COALESCE TOGETHER
  610. (OR EVEN RE-USE) FREED CHUNKS; IT RELIES UPON GARBAGE COLLECTING TO GET RID OF
  611. THE FREE CHUNKS.  ╘HE SCHEME IMPLEMENTED HERE IS MORE STATIC (INTERESTING WORD
  612. TO CHOOSE) IN THAT ONCE YOU ARE ALLOCATED A CHUNK, THAT CHUNK IS PINNED TO
  613. THAT ADDRESS AND WILL NEVER MOVE.  ╘HIS STATIC ORGANIZATION CAN LEAD TO THE
  614. PROBLEM OF MEMORY FRAGMENTATION, WHERE LOTS OF MEMORY CAN BE FREE BUT IS IN
  615. UN-COALESCABLE CHUNKS THAT ARE TOO SMALL TO BE USEFUL.  ╧H WELL.  ╔ DON'T
  616. THINK THAT IT IS REALLY A PROBLEM FOR STORING LINES OF TEXT AS INDIVIDUAL
  617. RECORDS, AND IT IS NO PROBLEM AT ALL FOR A PROGRAM THAT ALWAYS USES FIXED SIZE
  618. RECORDS.
  619.  
  620. 3.3. ╘╚┼ ╙╧╥╘ ╒╘╔╠╔╘┘
  621.  
  622. ╘HE WAY THAT THE SORT UTILITY MAKES FULL USE OF THE CAPABILITES OF THE
  623. PACKAGE.  ╞IRST IT READS IN THE INPUT FILE ONE LINE AT A TIME AND STORES THE
  624. LINES IN A LINKED LIST AS INDIVIDUAL RECORDS OF THE FORM:
  625.  
  626.   +--------+--------+--------+--------+-------...-----+--------+
  627.   ▄ ╬EXT   ▄ ╬EXT   ▄ ╬EXT   ▄ ╘OTAL  ▄               ▄        ▄
  628.   ▄ LINE   ▄ LINE   ▄ LINE   ▄ RECORD ▄  CHARACTERS   ▄ .BYTE  ▄
  629.   ▄ PTR    ▄ PTR    ▄ PTR    ▄ LENGTH ▄  OF THE LINE  ▄    $00 ▄
  630.   ▄ LOW    ▄ HIGH   ▄ BANK   ▄        ▄               ▄        ▄
  631.   +--------+--------+--------+--------+-------...-----+--------+
  632.     LINE+0   LINE+1   LINE+2   LINE+3     LINE+4        LINE+?
  633.  
  634. ╬OTE THAT THESE ARE VARIABLE LENGTH RECORDS; EACH RECORD IS ONLY AS LONG AS IT
  635. HAS TO BE.  ╘HE TOTAL RECORD LENGTH IS STORED AT THE FRONT OF THE RECORD.  ╔N
  636. ORDER TO READ A LINE INTO A PROCESSING BUFFER, A "ZPLOAD" IS DONE THAT READS
  637. THE FIRST FOUR BYTES OF THE RECORD IN ORDER TO GET THE LENGTH OF THE RECORD.
  638. ╘HEN THE ENTIRE RECORD CAN BE FETCHED SINCE ITS LENGTH IS KNOWN AT THAT TIME.
  639. ┼ACH RECORD ENDS WITH A $00 BYTE TO SIMPLIFY THE STRING COMPARISON
  640. SUBROUTINE.
  641.  
  642. ╘HE LINE LIST IS MAINTAINED IN ALPHABETICAL ORDER (ACTUALLY, REVERSE
  643. ALPHABETICAL ORDER; BELOW).  ╫HEN A NEW LINE IS READ IN FROM THE INPUT FILE,
  644. THE LINE LIST IS SEARCHED FOR THE TWO OTHER LINES WHOSE VALUES STRADDLE THE
  645. VALUE OF THE NEW LINE.  ╘HE LINE IS THEN LINKED IN AT THAT POSITION IN THE
  646. LIST.  ╬O OTHER LINES HAVE TO BE MOVED AROUND SINCE POINTERS ARE USED TO
  647. MAINTAIN THE ORDER OF THE LIST.  ╔N ORDER FOR A LINE ALREADY IN THE LIST TO BE
  648. COMPARED WITH THE NEW LINE, THE OLD LINE HAS TO BE FETCHED FROM FAR MEMORY
  649. (USING THE ZPLOAD + FETCH SCHEME ABOVE) INTO A WORK BUFFER IN THE ╙┘╙0 BANK.
  650. ╧N AVERAGE, HALF OF THE EXISTING LIST WILL HAVE TO BE SEARCHED IN THIS WAY IN
  651. ORDER TO FIND THE CORRECT SPOT TO INSERT THE NEW LINE.
  652.  
  653. ┴FTER THE POSITION FOR THE NEW LINE IS FOUND, SPACE FOR THE LINE IS ALLOCATED
  654. BY CALLING "MALLOC" AND THEN THE DATA IS STORED FROM THE WORK BUFFER IT WAS
  655. READ INTO TO FAR MEMORY.  ╘HE ZPLOAD AND ZPSTORE ROUTINES ARE USED TO MODIFY
  656. THE POINTERS TO LINK IN THE NEW LINE.  ┴ NUMBER OF POINTER MANIPULATIONS ARE
  657. ALSO REQUIRED ON THE ZERO PAGE VARIALBLES.
  658.  
  659. ╔F THE LINE LIST WAS GENERATED IN FORWARD ALPHABETIC ORDER, THEN THE UTILITY
  660. WOULD ACHIEVE ITS ╫╧╥╙╘ PERFORMANCE WHEN THE INPUT FILE WAS ALREADY MOSTLY OR
  661. PARTIALLY SORTED.  ╘HIS IS BECAUSE WHEN EACH LINE IS READ, IF IT COMES AFTER
  662. MOST OR ALL OF THE OTHER LINES, THE MOST OR ALL OF THE LINE LIST WOULD HAVE TO
  663. BE SEARCHED TO FIND THE FINAL RESTING POSITION FOR THE NEW LINE.  ╘HIS WOULD
  664. BE UNACCEPTABLE AND EXTREMELY WASTEFUL.  ┴ BETTER SCHEME IS TO GENERATE THE
  665. LINE LIST IN REVERSE ALPHABETIC ORDER.  ╘HEN, WHEN A "HIGHER VALUED" LINE IS
  666. READ IN, ITS CORRECT POSITION WOULD BE AT OR NEAR THE TOP OF THE LIST, SO ONLY
  667. IT WOULD ONLY HAVE TO BE COMPARED AGAINST A FEW OF THE LINES ALREADY ON THE
  668. LIST.  ╔N THE CASE OF AN INPUT FILE THAT IS ALREADY IN PRETTY MUCH RANDOM
  669. ORDER, IT MAKES NO DIFFERENCE WHETHER THE LIST IS IN FORWARD OR REVERSE
  670. ORDER.
  671.  
  672. ╙INCE THE LIST IS GENERATED IN REVERSE ORDER, IT MUST BE REVERESED AGAIN
  673. BEFORE WRITING IT TO THE OUTPUT FILE, SINCE THE USER WOULD WANT IT TO BE IN
  674. FORWARD ORDER (AND SINCE THIS IS THE ORDER THAT CAN BE MOST EASILY SORTED
  675. AGAIN LATER).  ┴ CLEVER LITTLE SUBROUTINE IS CALLED THAT REVERSES THE ORDER OF
  676. THE LIST.  ╔T ONLY HAS TO MAKE USE OF ZPLOAD AND ZPSTORE TO READ/CHANGE THE
  677. FIRST FEW BYTES OF EACH RECORD, SINCE IT IS NOT CONCERNED WITH THE DATA
  678. CONTENTS OF EACH RECORD.
  679.  
  680. ┴LTHOUGH THIS IS NOT STRICTLY NECESSARY, ALL OF THE RECORDS IN THE LINE LIST
  681. ARE FREED BEFORE THE SORT UTILITIY EXITS.  ╘HIS IS A GOOD PRACTICE, AND WOULD
  682. NECESSARY IF THE PROGRAM WERE TO CONTINUE TO DO USEFUL WORK AFTER WRITING THE
  683. SORTED FILE TO OUTPUT.  ┴ POINTER IS STEPPED THROUGH THE LIST (STARTING FROM
  684. THE HEAD POINTER) AND THE SPACE FOR EACH LINE IS DEALLOCATED BY CALLING FREE,
  685. AFTER DETERMINING THE SIZE OF THE RECORD BY READING THE FIRST FEW BYTES OF
  686. IT.  ╙INCE THE LIST WILL BE IN (PRETTY MUCH) RANDOM ORDER (OF ADDRESSES), THE
  687. DEALLOCATION MECHANISM DOES NOT ACHIEVE ITS BEST PERFORMANCE.
  688.  
  689. ┴ CONVENIENT JUMP TABLE IS SET UP AT THE START OF THE CODE TO MAKE IT EASIER
  690. FOR YOU TO LINK YOUR OWN PROGRAMS TO THE PACKAGE.  ═AKE SURE THAT ══╒
  691. CONFIGURATION VALUE $0┼ IS IN EFFECT BEFORE CALLING ANY OF THE ROUTINES.  ┘OU
  692. MAY HAVE TO MUCK WITH THE CODE A LITTLE BIT TO GET IT TO WORK FOR YOU.
  693.  
  694. ------------------------------------------------------------------------------
  695.  
  696. 4. ╞╧╥ ╘╚┼ ┼╪╨┼╥╘ ╚┴├╦┼╥
  697.  
  698. ┘OU GET TO SEE THE CODE THAT ACTUALLY IMPLEMENTS THE MEMORY PACKAGE AND THE
  699. SORT UTILITY.  ╔ HAVE IT HERE IN A SPECIAL FORM; EACH CODE LINE IS PRECEEDED
  700. BY A FEW SPECIAL CHARACTERS AND THE LINE NUMBER.  ╘HE LINE NUMBER IS THERE TO
  701. ALLOW ME TO REFER TO SPECIFIC LINES, AND THE SPECIAL CHARACTERS ARE THERE TO
  702. ALLOW YOU TO EASILY EXTRACT THE ASSEMBLER CODE FROM THE REST OF THIS MAGAZINE
  703. (AND ALL OF MY UGLY COMMENTS).  ╧N A ╒NIX SYSTEM, ALL YOU HAVE TO DO IS
  704. EXECUTE THE FOLLOWING COMMAND LINE (SUBSTITUTE FILENAMES AS APPROPRIATE):
  705.  
  706. GREP '^\.%....\!' ╚ACK2 ▄ SED 'S/^.%....\!..//' ▄ SED 'S/.%....\!//' >SORT.ASM
  707.  
  708. ─ONTCHA JUST LOVE THOSE ╒NIX COMMANDS!  ╚ERE IS THE ASSEMBLER CODE:
  709.  
  710. .%0001!  ;╙ORT UTILITY USING DYNAMIC MEMORY ALLOCATION WITH EXPANDED MEMORY
  711. .%0002!  ;WRITTEN 92/04/22 BY ├RAIG ┬RUCE FOR ├= ╚ACKING ╬ET ═AGAZINE
  712. .%0003!  ;--------------------------------------------------------------------
  713.  
  714. ╘HIS PROGRAM IS WRITTEN FOR THE ┬UDDY ASSEMBLER.  ╠IKE MOST ASSEMBLERS, IT
  715. NEEDS A FEW DIRECTIVES TO START OFF, SO HERE THEY ARE.  ╬OTE THAT MY COMMENTS
  716. COME ┬┼╞╧╥┼ THE SECTION OF CODE THAT ╔ AM COMMENTING ON.
  717.  
  718. .%0004!  .MEM
  719. .%0005!  .BANK 15
  720. .%0006!  .ORG $1300
  721. .%0007!
  722. .%0008!  ;*** GLOBAL DECLARATIONS
  723. .%0009!
  724.  
  725. ╚ERE ARE THE ZERO PAGE LOCATIONS THAT THE PACKAGE USES FOR ITS OWN PURPOSES.
  726. ╔ STUCK THE SYS╫ORK VARIABLE OVER THE ┬┴╙╔├ GRAPHICS COMMAND PARAMETERS SINCE
  727. IT SEEMS LIKE A GOOD PLACE.  ╔T REQUIRES 16 BYTES AND IS USED BY MOST OF THE
  728. ROUTINES FOR TEMPORARY STORAGE.  "TEMP1" IS USED FOR "VERY" TEMPORARY
  729. STORAGE.
  730.  
  731. .%0010!  ZP1 = $FA
  732. .%0011!  TEMP1 = $FD
  733. .%0012!  ZW1 = $FE
  734. .%0013!  SYS╫ORK = $80    ;16-BYTE BLOCK
  735. .%0014!
  736.  
  737. ╘HESE ARE THE NON-ZERO PAGE STORAGE LOCATIONS.  ╘HE COMMON CODE BUFFER PRETTY
  738. MUCH HAS TO BE AT $200 SINCE THAT IS (ABOUT) THE ONLY FREE SECTION OF MEMORY
  739. BELOW ADDRESS $0400 (IN THE COMMON MEMORY RANGE).
  740.  
  741. .%0015!  COM├ODE┬UFFER = $200
  742. .%0016!  WORK┬UFFER = $B00
  743. .%0017!
  744.  
  745. ╘HESE ARE THE ══╒ CONFIGURATION REGISTER VALUES AND SOME IMPORTANT ╔/╧
  746. ADDRESSES.
  747.  
  748. .%0018!  BK╙YS = $0E
  749. .%0019!  BK╦ERNEL = $00
  750. .%0020!  BK╙ELECT = $FF00
  751. .%0021!  BK╙ELECT╥AM0 = $FF01
  752. .%0022!  BK╙ELECT╥AM1 = $FF02
  753. .%0023!  BK╥AM0 = $3F
  754. .%0024!  BK╥AM1 = $7F
  755. .%0025!  BK┼XP0 = $80
  756. .%0026!  BK╬ULL = $FF
  757. .%0027!  ZP╙ELECT = $D507
  758. .%0028!  REU = $DF00
  759. .%0029!  VIC = $D000
  760. .%0030!
  761. .%0031!  ERR╔NSUFFICIENT═EMORY = 1
  762. .%0032!
  763. .%0033!  ;*** JUMP TO MAIN ROUTINE
  764. .%0034!
  765. .%0035!     JMP MAIN
  766. .%0036!
  767. .%0037!  ;*** JUMP TABLE
  768. .%0038!
  769.  
  770. ╚ERE'S THAT JUMP TABLE.
  771.  
  772. .%0039!  STARTUP   JMP INTERN╙TARTUP
  773. .%0040!  SHUTDOWN  JMP INTERN╙HUTDOWN
  774. .%0041!  ZPLOAD    JMP INTERN┌P╠OAD
  775. .%0042!  ZPSTORE   JMP INTERN┌P╙TORE
  776. .%0043!  FETCH     JMP INTERN╥AM0╞ETCH
  777. .%0044!  STASH     JMP INTERN╥AM0╙TASH
  778. .%0045!  MALLOC    JMP INTERN┴LLOC
  779. .%0046!  FREE      JMP INTERN╞REE
  780. .%0047!
  781. .%0048!  ;*** STORAGE
  782. .%0049!
  783.  
  784. ╚ERE ARE SOME USEFUL STORAGE LOCATIONS.  "ERRNO" CONTAINS THE CODE FOR THE
  785. ERROR ENCOUNTERED IN A ROUTINE IF THE ROUTINE EXITS WITH THE CARRY FLAG SET
  786. (AND IT IS SUPPOSED TO BE CLEARED FOR ╧╦).  "N┼XP┬ANKS" GIVES THE NUMBER OF
  787. EXPANSION MEMORY BANKS, AND "FREE═EMORY" GIVES THE NUMBER OF BYTES CURRENTLY
  788. FREE IN THE SYSTEM.  ┬OTH OF THESE ARE USEFUL STATUS VALUES AND CAN BE READ
  789. DIRECTLY.
  790.  
  791. .%0050!  ERRNO      .BUF 1
  792. .%0051!  N┼XP┬ANKS  .BUF 1
  793. .%0052!  MALLOC╚EAD .BUF 3
  794. .%0053!  FREE═EMORY .BUF 3
  795. .%0054!
  796. .%0055!  ;***STARTUP
  797. .%0056!
  798.  
  799. ╘HIS ROUTINE GETS THE BALL ROLLING.  ╔T CLEARS THE STATUS REGISTER IN CASE YOU
  800. START UP THE SYSTEM WITH THE DECIMAL MODE FLAG SET OR INTERRUPTS DISABLED.
  801.  
  802. .%0057!  INTERN╙TARTUP = *
  803. .%0058!     LDA #0
  804. .%0059!     PHA
  805. .%0060!     PLP
  806. .%0061!     LDA #BK╙YS
  807. .%0062!     STA BK╙ELECT
  808. .%0063!     JSR INSTALL├OMMON├ODE
  809. .%0064!     JSR SNIFF╥┼╒
  810. .%0065!     JSR INIT─YNAMIC═EMORY
  811. .%0066!     RTS
  812. .%0067!
  813.  
  814. ┴ND THIS ROUTINE STOPS THE BALL FROM ROLLING.  ╔ FILL THE ┬┴╙╔├ COMMAND LINE
  815. BUFFER WITH ZEROS TO STOP THAT SYNTAX ERROR THING.
  816.  
  817. .%0068!  INTERN╙HUTDOWN = *
  818. .%0069!     LDX #0
  819. .%0070!     LDA #0
  820. .%0071!  -  STA $200,X
  821. .%0072!     INX
  822. .%0073!     CPX #COM├ODE┼ND-COM├ODE╙TART
  823. .%0074!     BNE -
  824. .%0075!     LDA #BK╦ERNEL
  825. .%0076!     STA BK╙ELECT
  826. .%0077!     RTS
  827. .%0078!
  828. .%0079!  ;***INSTALL COMMON CODE
  829. .%0080!
  830.  
  831. ╘HIS ROUTINE COPIES THE COMMON CODE SUBROUTINES INTO THE COMMON CODE BUFFER
  832. (AT $0200).
  833.  
  834. .%0081!  INSTALL├OMMON├ODE = *
  835. .%0082!     LDX #0
  836. .%0083!  -  LDA COM├ODE╙TART,X
  837. .%0084!     STA COM├ODE┬UFFER,X
  838. .%0085!     INX
  839. .%0086!     CPX #COM├ODE┼ND-COM├ODE╙TART
  840. .%0087!     BCC -
  841. .%0088!     RTS
  842. .%0089!
  843. .%0090!  ;--------------------------------------------------------------------
  844. .%0091!  ;***COMMON CODE
  845. .%0092!
  846.  
  847. ┴ND THIS IS THE COMMON CODE.  ╔T CONTAINS FOUR SUBROUTINES FOR ACCESSING ╥┴═1
  848. (AND THE ZERO PAGE ROUTINES ARE USED FOR ╥┴═0 AS WELL).
  849.  
  850. .%0093!  COM├ODE╙TART = *
  851. .%0094!
  852.  
  853. ╙ELECTS THE ══╒ CONFIGURATION ACCORDING TO THE BANK NUMBER AND COPIES THE
  854. NUMBER OF BYTES REQUIRED FOR A ZPLOAD.  ╔T EXITS BY RESTORING THE ╙┘╙ BANK.
  855. ╘HIS IS USED ONLY FOR INTERNAL MEMORY ZPLOADS.
  856.  
  857. .%0095!  COM┌P╠OAD = *
  858. .%0096!     LDA ZP1+2
  859. .%0097!     STA BK╙ELECT
  860. .%0098!     STY TEMP1
  861. .%0099!     LDY #0
  862. .%0100!  -  LDA (ZP1),Y
  863. .%0101!     STA 0,X
  864. .%0102!     INX
  865. .%0103!     INY
  866. .%0104!     CPY TEMP1
  867. .%0105!     BCC -
  868. .%0106!     LDA #BK╙YS
  869. .%0107!     STA BK╙ELECT
  870. .%0108!     RTS
  871. .%0109!
  872.  
  873. ╨RETTY MUCH THE SAME AS ZPLOAD.
  874.  
  875. .%0110!  COM┌P╙TORE = *
  876. .%0111!     LDA ZP1+2
  877. .%0112!     STA BK╙ELECT
  878. .%0113!     STY TEMP1
  879. .%0114!     LDY #0
  880. .%0115!  -  LDA 0,X
  881. .%0116!     STA (ZP1),Y
  882. .%0117!     INX
  883. .%0118!     INY
  884. .%0119!     CPY TEMP1
  885. .%0120!     BCC -
  886. .%0121!     LDA #BK╙YS
  887. .%0122!     STA BK╙ELECT
  888. .%0123!     RTS
  889. .%0124!
  890.  
  891. ┴S THE NAME SUGGESTS, THIS COPIES FROM ╥┴═1 TO ╥┴═0.  ╧NLY .┘ NUMBER OF BYTES
  892. ARE COPIED, AND IF .┘=0, 256 BYTES ARE COPIED.  ┘OU'LL NOTICE THAT THE ══╒
  893. CONFIGURATIONS ARE SWITCHED BETWEEN FOR EVERY BYTE COPIED.  ╘HIS IS NOT THE
  894. MOST EFFICIENT SCHEME, BUT IT SUFFICES.  ╘HE ══╒ PRECONFIGURATION REGISTERS
  895. ARE USED AND THE VALUE THAT ┬┴╙╔├ PUT IN THEM ARE ASSUMED TO STILL BE THERE.
  896.  
  897. .%0125!  COM├OPY╥AM1╘O╥AM0 = *
  898. .%0126!     DEY
  899. .%0127!     BEQ +
  900. .%0128!  -  STA BK╙ELECT╥AM1
  901. .%0129!     LDA (ZP1),Y
  902. .%0130!     STA BK╙ELECT╥AM0
  903. .%0131!     STA (ZW1),Y
  904. .%0132!     DEY
  905. .%0133!     BNE -
  906. .%0134!  +  STA BK╙ELECT╥AM1
  907. .%0135!     LDA (ZP1),Y
  908. .%0136!     STA BK╙ELECT╥AM0
  909. .%0137!     STA (ZW1),Y
  910. .%0138!     LDA #BK╙YS
  911. .%0139!     STA BK╙ELECT
  912. .%0140!     RTS
  913. .%0141!
  914.  
  915. ╘HE OPPOSITE DIRECTION.
  916.  
  917. .%0142!  COM├OPY╥AM0╘O╥AM1 = *
  918. .%0143!     DEY
  919. .%0144!     BEQ +
  920. .%0145!  -  STA BK╙ELECT╥AM0
  921. .%0146!     LDA (ZW1),Y
  922. .%0147!     STA BK╙ELECT╥AM1
  923. .%0148!     STA (ZP1),Y
  924. .%0149!     DEY
  925. .%0150!     BNE -
  926. .%0151!  +  STA BK╙ELECT╥AM0
  927. .%0152!     LDA (ZW1),Y
  928. .%0153!     STA BK╙ELECT╥AM1
  929. .%0154!     STA (ZP1),Y
  930. .%0155!     LDA #BK╙YS
  931. .%0156!     STA BK╙ELECT
  932. .%0157!     RTS
  933. .%0158!
  934.  
  935. ╘HE END OF THE COMMON CODE.  ╘HE LENGTH OF THE COMMON CODE IS DETERMINED BY
  936. SUBTRACTING THE END ADDRESS FROM THE START ADDRESS.
  937.  
  938. .%0159!  COM├ODE┼ND = *
  939. .%0160!
  940. .%0161!  ;--------------------------------------------------------------------
  941. .%0162!  ;*** ZPLOAD( [ZP1]=╙OURCE, .╪=┌P─EST, .┘=╠ENGTH )
  942. .%0163!
  943.  
  944. ╘HE ACTUAL ZPLOAD ROUTINE.  ╔T DISPATCHES TO THE COMMON CODE ROUTINE IF
  945. INTERNAL MEMORY IS SPECIFIED BY THE FAR POINTER, OR FALLS THROUGH TO ╥┼╒ CODE
  946. IF EXPANSION MEMORY IS SPECIFIED.
  947.  
  948. .%0164!  INTERN┌P╠OAD = *
  949. .%0165!     LDA ZP1+2
  950. .%0166!     BMI +
  951. .%0167!     JMP COM┌P╠OAD-COM├ODE╙TART+COM├ODE┬UFFER
  952. .%0168!  +  STY REU+7
  953. .%0169!     LDY #$91
  954. .%0170!
  955.  
  956. ╙ETS UP THE ╥┼╒ ├ONTROLLER REGISTERS FOR THE PARAMETERS OF THE TRANSFER.  ╬OTE
  957. THAT THE VALUE OF THE ZERO PAGE ADDRESS IS NOT ASSUMED TO BE ABSOLUTE $0000
  958. BUT IS TAKEN FROM THE ZERO PAGE SELECTION REGISTER OF THE ══╒.  ╘HE ╥┼╒
  959. ├ONTROLLER DOES NOT USE THE ══╒ FOR DECODING ZERO PAGE AND STACK PAGE
  960. ADDRESSES; IT ACCESSES THE ABSOLUTE MEMORY DIRECTLY.
  961.  
  962. .%0171!  ZERO╨AGE╥EU╧P = *
  963. .%0172!     STA REU+6
  964. .%0173!     STX REU+2
  965. .%0174!     LDA ZP╙ELECT
  966. .%0175!     STA REU+3
  967. .%0176!     LDA ZP1
  968. .%0177!     STA REU+4
  969. .%0178!     LDA ZP1+1
  970. .%0179!     STA REU+5
  971. .%0180!     LDA #0
  972. .%0181!     STA REU+8
  973.  
  974. ╚ERE THE SYSTEM CLOCK SPEED IS PUT INTO ╙LOW MODE WHILE THE TRANSFER OCCURS
  975. AND IS THEN RESTORED.  ╘HIS IS NECESSARY.
  976.  
  977. .%0182!     LDA VIC+$30
  978. .%0183!     LDX #$00
  979. .%0184!     STX VIC+$30
  980. .%0185!     STY REU+1
  981. .%0186!     STA VIC+$30
  982. .%0187!     RTS
  983. .%0188!
  984. .%0189!  ;*** ZPSTORE( .╪=┌P╙OURCE, [ZP1]=─EST, .┘=╠ENGTH )
  985. .%0190!
  986.  
  987. ╨RETTY MUCH THE SAME AS THE ZPLOAD ROUTINE, EXCEPT THAT A COMMAND CODE FOR THE
  988. ╥┼╒ ├ONTROLLER IS DIFFERENT (SPECIFYING AN INTERNAL TO EXPANSION MEMORY
  989. TRANSFER).  ╘HE ╥┼╒ CODE IN THE ZPLOAD ROUTINE IS CALLED.
  990.  
  991. .%0191!  INTERN┌P╙TORE = *
  992. .%0192!     LDA ZP1+2
  993. .%0193!     BMI +
  994. .%0194!     JMP COM┌P╙TORE-COM├ODE╙TART+COM├ODE┬UFFER
  995. .%0195!  +  STY REU+7
  996. .%0196!     LDY #$90
  997. .%0197!     JMP ZERO╨AGE╥EU╧P
  998. .%0198!
  999. .%0199!  ;--------------------------------------------------------------------
  1000.